<?php

namespace app\common\queue;

use app\admin\model\Job;
use app\admin\model\Order;
use think\Db;
use think\Log;
use think\queue\Job as Jobs;

class End
{
    /**
     * fire是消息队列默认调用的方法
     * @param Jobs $job 当前的任务对象
     * @param mixed $data 发布任务时自定义的数据
     */
    public function fire(Jobs $job, $data)
    {
        // 有效消息到达消费者时可能已经不再需要执行了
        if (!$this->checkJob($data)) {
            $job->delete();
            return;
        }

        // 执行业务处理
        if ($this->doJob($data)) {
            $job->delete();// 任务执行成功后删除
            Log::log("自动[ 结束 ]任务成功执行");
        } else {
            //检查任务重试次数
            if ($job->attempts() > 3) {
                Log::log("在日志不会看到这句话");
                $job->delete();
            }
        }
    }

    /**
     * 消息在到达消费者时可能已经不需要执行了
     * @param mixed $data 发布任务时自定义的数据
     * @return boolean 任务执行的结果
     */
    private function checkJob($data)
    {
        // queue_update 值不对应则说明发生改变 那么任务终止
        // 判断订单是否存在 判断状态
        $id   = $data['id'];
        $date = date("Y-m-d H:i:s");
        $find = Db::name('job')->where(['id' => $data['id']])->find();
        if ($find) {
            if ($find['status'] != 3) {
                Log::log("[ 招聘结束失败:记录已找到，但状态值不为3（进行中） ] [ 招聘ID: $id ] [ 时间: $date]");
                return false;
            } elseif ($find['queue_update'] != $data['queue_update']) {
                Log::log("[ 招聘结束中止:记录已找到，这是修改之前的版本 ] [ 招聘ID: $id ] [ 时间: $date]");
                return false;
            } else {
                return true;
            }
        } else {
            Log::log("[ 招聘结束失败:记录未找到 ] [ 招聘ID: $id ] [ 时间: $date]");
            return false;
        }
    }

    /**
     * 根据消息中的数据进行实际的业务处理
     * @param mixed $data 发布任务时自定义的数据
     * @return boolean 任务执行的结果
     */
    private function doJob($data)
    {
        $id   = $data['id'];
        $date = date("Y-m-d H:i:s");

        $model_job = new Job();
        // 这里需要调整 订单信息 job信息
        $find = $model_job->where(['id' => $id, 'status' => 3])->find();
        if ($find) {
            // 调整job
            $find->save(['status' => 4]);
            $model  = new Order();
            $select = $model->where(['job_id' => $id, 'status' => 2])->select();

            // 判断订单是否异常 计算工资
            foreach ($select as $item) {
                $is_abnormal = false;
                // 酒店
                if ($item->company_hour < $item->time_hour) { // 酒店打卡时长不足 设定值 订单异常
                    $item->status        = 6;
                    $item->is_abnormal   = 1;
                    $item->abnormal_text = '酒店打卡时长,不足工作时长';
                    $is_abnormal         = true;
                }

                // 小时工打卡
                if ($item->fix_hour != null) { // 手动修改过工作时长
                    if ($item->fix_hour < $item->time_hour) { // 修改过打卡时长仍然不足 设定值 订单异常
                        $item->status        = 6;
                        $item->is_abnormal   = 1;
                        $item->abnormal_text = '酒店调整了工作时长，仍然不足工作时长';
                        $is_abnormal         = true;
                    }
                } else { // 没修改时长时 判断小时工 打卡时长即可
                    if ($item->duration_hour < $item->time_hour) { // 正常打卡时长不足 设定值 订单异常 给这个
                        $item->status        = 6;
                        $item->is_abnormal   = 1;
                        $item->abnormal_text = '小时工打卡时长,不足工作时长';
                        $is_abnormal         = true;
                        // 用户添加异常次数
                        $item->user()->setInc('error_times');
                    }
                }

                // 订单异常还是完成
                if ($is_abnormal) { // 完成：最终结算时长，最终结算金额
                    $item->total_time = $item->fix_hour ? $item->fix_hour : $item->duration_hour;
                    $all_price        = $item->total_time * $item->price - $item->total_time - 10;
                    $item->all_price  = $all_price < 0 ? 0 : $all_price;
                }

                $item->isUpdate(true)->save();
            }
        } else {
            Log::log("[ 招聘结束失败:记录未找到 ] [ 招聘ID: $id ] [ 时间: $date]");
        }

        // 处理失败也返回 true
        return true;
    }
}